﻿// (c) Copyright Michael Antonio.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization;
#if WINDOWS_PHONE
using Microsoft.Phone.Shell;
#endif

namespace MichMan.Utilities
{
    /// <summary>
    /// Rather than have one settings file, the different components of the app save their own state.
    /// This class facilitates that by saving and loading the data at the correct times. 
    /// Data is loaded on-demand, and saved only if it has been accessed.
    /// 
    /// All settings data is stored in the "settings" folder in isolated storage.
    /// 
    /// The assumption is that there will be one settings file for each type of data.
    /// 
    /// If you need to have multiple settings of the same type, either create a Dictionary or other data contract 
    /// container class to store them all or create subclasses.  
    /// </summary>
    /// <typeparam name="TSettingsType">Data contract type for the settings.</typeparam>
    public class Settings<TSettingsType> where TSettingsType : class, new()
    {
        private Settings()
        {
#if WINDOWS_PHONE
            PhoneApplicationService.Current.Deactivated += new EventHandler<DeactivatedEventArgs>(Current_Deactivated);
            PhoneApplicationService.Current.Activated += new EventHandler<ActivatedEventArgs>(Current_Activated);
            PhoneApplicationService.Current.Closing += new EventHandler<ClosingEventArgs>(Current_Closing);
#endif
        }

        private TSettingsType _data = null;

        public TSettingsType Data
        {
            get
            {
                if (_data == null)
                {
                    _data = Load();
                }
                return _data;
            }
        }

        public static TSettingsType Instance
        {
            get
            {
                return Singleton<Settings<TSettingsType>>.Create(() => new Settings<TSettingsType>()).Data;
            }
        }

        public static string SettingsDirectory
        {
            get
            {
                return "settings";
            }
        }

        public static string SettingsFileName 
        {
            get
            {
                return Path.Combine(SettingsDirectory, typeof(TSettingsType).FullName + ".xml");
            }
        }

        public static void Save()
        {
            /*
            if (Singleton<Settings<TSettingsType>>.Get() != null && Singleton<Settings<TSettingsType>>.Get()._data != null)
            {
                try
                {
                    IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
                    if (!iso.DirectoryExists(SettingsDirectory))
                    {
                        iso.CreateDirectory(SettingsDirectory);
                    }

                    using (Stream stream = iso.OpenFile(SettingsFileName, FileMode.Create))
                    {
                        DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(TSettingsType));
                        dataContractSerializer.WriteObject(stream, Instance);
                        stream.Flush();
                    }
                }
                catch
                {
                }
            }
             */
        }

        protected static TSettingsType Load()
        {
            return new TSettingsType();
            /*
            try
            {
                IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();

                if (!iso.FileExists(SettingsFileName))
                {
                    return new TSettingsType();
                }

                using (Stream stream = iso.OpenFile(SettingsFileName, FileMode.Open))
                {
                    DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(TSettingsType));
                    return (TSettingsType)dataContractSerializer.ReadObject(stream);
                }
            }
            catch (Exception e)
            {
                try
                {
                    IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();
                    iso.DeleteFile(SettingsFileName);
                }
                catch
                {
                }
                Debug.WriteLine(e.Message);
                return new TSettingsType();
            }
             */
        }

#if WINDOWS_PHONE
        void Current_Closing(object sender, ClosingEventArgs e)
        {
            Save();
        }

        void Current_Activated(object sender, ActivatedEventArgs e)
        {
            _data = Load();
        }

        void Current_Deactivated(object sender, DeactivatedEventArgs e)
        {
            Save();
        }
#endif
    }
}
